package com.lyn.seckill.service.impl;

import com.lyn.seckill.common.error.BusinessException;
import com.lyn.seckill.common.error.EnumBusinessError;
import com.lyn.seckill.dao.UserInfoDoMapper;
import com.lyn.seckill.dao.UserPasswordDoMapper;
import com.lyn.seckill.dataobject.UserInfoDo;
import com.lyn.seckill.dataobject.UserPasswordDo;
import com.lyn.seckill.service.UserService;
import com.lyn.seckill.service.model.UserModel;
import com.lyn.seckill.validator.ValidationResult;
import com.lyn.seckill.validator.ValidatorImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl implements UserService {


    private final UserInfoDoMapper userInfoDoMapper;
    private final UserPasswordDoMapper userPasswordDoMapper;
    private final ValidatorImpl validator;
    @Autowired
    public UserServiceImpl(UserInfoDoMapper userInfoDoMapper, UserPasswordDoMapper userPasswordDoMapper, ValidatorImpl validator) {
        this.userInfoDoMapper = userInfoDoMapper;
        this.userPasswordDoMapper = userPasswordDoMapper;
        this.validator = validator;
    }

    /**
     * 用户注册服务
     * @param userModel
     * @throws BusinessException
     */
    @Override
    @Transactional
    public void register(UserModel userModel) throws BusinessException {
        if (userModel == null) {
            throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR);
        }
        // 校验优化
//        if (StringUtils.isEmpty(userModel.getName())
//                || userModel.getGender() == null
//                || userModel.getAge() == null
//                || StringUtils.isEmpty(userModel.getTelephone())) {
//            throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR);
//        }
        ValidationResult validate = validator.validate(userModel);
        if (validate.isHasError()) {
            throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR,validate.getErrorMessage());
        }

        UserInfoDo userInfoDo = convertFromModel(userModel);
        try{
            userInfoDoMapper.insertSelective(userInfoDo);
        } catch (DuplicateKeyException de) {
            throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR,"手机号已注册");
        }
        userModel.setId(userInfoDo.getId());
        UserPasswordDo userPasswordDo = convertPasswordFromModel(userModel);
        userPasswordDoMapper.insertSelective(userPasswordDo);
    }

    /**
     * 获取用户信息服务
     * @param ID
     * @return
     */
    @Override
    public UserModel getUserById(Integer ID) {
        UserInfoDo userInfoDo = userInfoDoMapper.selectByPrimaryKey(ID);
        if (userInfoDo == null) {
            return null;
        }
        UserPasswordDo userPasswordDo = userPasswordDoMapper.selectByUserId(userInfoDo.getId());
        return convertFromDataObject(userInfoDo,userPasswordDo);
    }

    /**
     * 登录服务
     * @param telephone
     * @param encryptPassword
     * @throws BusinessException
     */
    @Override
    public UserModel validateLogin(String telephone, String encryptPassword) throws BusinessException {
        // 通过用户的手机获取用户信息
        UserInfoDo userInfoDo = userInfoDoMapper.selectByTelephone(telephone);
        if (userInfoDo == null) {
            throw new BusinessException(EnumBusinessError.USER_LOGIN_FAILURE);
        }
        UserPasswordDo userPasswordDo = userPasswordDoMapper.selectByUserId(userInfoDo.getId());
        UserModel userModel = convertFromDataObject(userInfoDo, userPasswordDo);
        // 比对用户信息内加密的密码是否和传输进来的密码匹配
        if (!StringUtils.equals(encryptPassword,userModel.getEncryptPassword())) {
            throw new BusinessException(EnumBusinessError.USER_LOGIN_FAILURE);
        }
        userModel.setEncryptPassword("不给你看");
        return userModel;
    }

    /**
     * 将持久层获取的数据对象（DO）转换为核心领域模型对象（MO），提供给控制层使用
     * @param userInfoDo
     * @param userPasswordDo
     * @return
     */
    private UserModel convertFromDataObject(UserInfoDo userInfoDo, UserPasswordDo userPasswordDo) {
        if (userInfoDo == null) {
            return null;
        }
        UserModel userModel = new UserModel();
        BeanUtils.copyProperties(userInfoDo,userModel);
        if (userPasswordDo != null) {
            userModel.setEncryptPassword(userPasswordDo.getEncryptPassword());
        }
        return userModel;
    }

    /**
     * 将核心领域模型对象（MO）转换为用户信息模型对象
     * @param userModel
     * @return
     */
    private UserInfoDo convertFromModel(UserModel userModel) {
        if (userModel == null) {
            return null;
        }
        UserInfoDo userInfoDo = new UserInfoDo();
        BeanUtils.copyProperties(userModel,userInfoDo);
        return userInfoDo;
    }

    /**
     * 将核心领域模型对象（MO）转换为用户密码模型对象
     * @param userModel
     * @return
     */
    private UserPasswordDo convertPasswordFromModel(UserModel userModel) {
        if (userModel == null) {
            return null;
        }
        UserPasswordDo userPasswordDo = new UserPasswordDo();
        userPasswordDo.setEncryptPassword(userModel.getEncryptPassword());
        userPasswordDo.setUserId(userModel.getId());
        return userPasswordDo;
    }
}
